Formula One (a.k.a. F1) is an international auto racing sport. It is the highest level of single-seat, open-wheel and open-cockpit professional motor racing contest and is is governed and sanctioned by a world body called the FIA − Fédération Internationale de l'Automobile(FIA).The name ‘Formula’ comes from the set of rules that the participating cars and drivers must follow.F1 season consists of a series of races, known as Grands Prix, which take place worldwide on purpose-built circuits and on public roads.
import pandas as pd
import numpy as np
import datetime as dt
import matplotlib.pyplot as plt
import seaborn as sns
import os
import warnings
import folium
import ipywidgets as widgets
import plotly.express as px
import plotly.graph_objects as go
import plotly.offline as pyo
from IPython.display import display, HTML
pyo.init_notebook_mode()
display(HTML("<style>.container { width:100% !important; }</style>"))
pd.set_option('display.max_columns', None)
pd.set_option('display.max_colwidth', None)
pd.set_option('display.max_rows', 50)
warnings.filterwarnings("ignore")
The dataset consists of all information on the Formula 1 such as races, drivers, constructors, qualifying, circuits, lap times, pit stops, championships etc. from 1950 till the end of 2022 season.
Full dataset is available at http://ergast.com/mrd/.
#Reading all data sets
data_url="https://github.com/madrian98/Formula1DataExploration/blob/main/Data"
data_raw="?raw=true"
races = pd.read_csv((data_url+"/races.csv"+data_raw))
drivers = pd.read_csv((data_url+"/drivers.csv"+data_raw))
constructors = pd.read_csv((data_url+"/constructors.csv"+data_raw))
results = pd.read_csv((data_url+"/results.csv"+data_raw))
circuits = pd.read_csv((data_url+"/circuits.csv"+data_raw))
#Races
races.info()
#Drivers
drivers.info()
#Constructors
constructors.info()
#Results
results.info()
#Circuits
circuits.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 1079 entries, 0 to 1078 Data columns (total 18 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 raceId 1079 non-null int64 1 year 1079 non-null int64 2 round 1079 non-null int64 3 circuitId 1079 non-null int64 4 name 1079 non-null object 5 date 1079 non-null object 6 time 1079 non-null object 7 url 1079 non-null object 8 fp1_date 1079 non-null object 9 fp1_time 1079 non-null object 10 fp2_date 1079 non-null object 11 fp2_time 1079 non-null object 12 fp3_date 1079 non-null object 13 fp3_time 1079 non-null object 14 quali_date 1079 non-null object 15 quali_time 1079 non-null object 16 sprint_date 1079 non-null object 17 sprint_time 1079 non-null object dtypes: int64(4), object(14) memory usage: 151.9+ KB <class 'pandas.core.frame.DataFrame'> RangeIndex: 855 entries, 0 to 854 Data columns (total 9 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 driverId 855 non-null int64 1 driverRef 855 non-null object 2 number 855 non-null object 3 code 855 non-null object 4 forename 855 non-null object 5 surname 855 non-null object 6 dob 855 non-null object 7 nationality 855 non-null object 8 url 855 non-null object dtypes: int64(1), object(8) memory usage: 60.2+ KB <class 'pandas.core.frame.DataFrame'> RangeIndex: 211 entries, 0 to 210 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 constructorId 211 non-null int64 1 constructorRef 211 non-null object 2 name 211 non-null object 3 nationality 211 non-null object 4 url 211 non-null object dtypes: int64(1), object(4) memory usage: 8.4+ KB <class 'pandas.core.frame.DataFrame'> RangeIndex: 25840 entries, 0 to 25839 Data columns (total 18 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 resultId 25840 non-null int64 1 raceId 25840 non-null int64 2 driverId 25840 non-null int64 3 constructorId 25840 non-null int64 4 number 25840 non-null object 5 grid 25840 non-null int64 6 position 25840 non-null object 7 positionText 25840 non-null object 8 positionOrder 25840 non-null int64 9 points 25840 non-null float64 10 laps 25840 non-null int64 11 time 25840 non-null object 12 milliseconds 25840 non-null object 13 fastestLap 25840 non-null object 14 rank 25840 non-null object 15 fastestLapTime 25840 non-null object 16 fastestLapSpeed 25840 non-null object 17 statusId 25840 non-null int64 dtypes: float64(1), int64(8), object(9) memory usage: 3.5+ MB <class 'pandas.core.frame.DataFrame'> RangeIndex: 76 entries, 0 to 75 Data columns (total 9 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 circuitId 76 non-null int64 1 circuitRef 76 non-null object 2 name 76 non-null object 3 location 76 non-null object 4 country 76 non-null object 5 lat 76 non-null float64 6 lng 76 non-null float64 7 alt 76 non-null object 8 url 76 non-null object dtypes: float64(2), int64(1), object(6) memory usage: 5.5+ KB
#joining results on drivers on driverID(inner join)
dfDriver_res = pd.merge(results,drivers,on='driverId')
#joining previously created table on races by raceID(inner join)
dfConstructor_res = pd.merge(dfDriver_res,races,on='raceId')
#joining previously created table on constructors by constructorID(inner join)
dfRaceResults = pd.merge(dfConstructor_res,constructors,on='constructorId')
#Creating driver full name column
dfRaceResults['full_name'] = dfRaceResults['forename'] + ' ' + dfRaceResults['surname']
#Removing unnecessary columns
dfRaceResults = dfRaceResults.drop(columns=['url_x','url_y','name_y','nationality_y','url','time_y','fp1_date','fp1_time','fp2_date','fp2_time','fp3_date','fp3_time','quali_date','sprint_date','sprint_time'])
#Display data
dfRaceResults.head(5)
| resultId | raceId | driverId | constructorId | number_x | grid | position | positionText | positionOrder | points | laps | time_x | milliseconds | fastestLap | rank | fastestLapTime | fastestLapSpeed | statusId | driverRef | number_y | code | forename | surname | dob | nationality_x | year | round | circuitId | name_x | date | quali_time | constructorRef | full_name | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 18 | 1 | 1 | 22 | 1 | 1 | 1 | 1 | 10.0 | 58 | 1:34:50.616 | 5690616 | 39 | 2 | 1:27.452 | 218.300 | 1 | hamilton | 44 | HAM | Lewis | Hamilton | 1985-01-07 | British | 2008 | 1 | 1 | Australian Grand Prix | 2008-03-16 | \N | mclaren | Lewis Hamilton |
| 1 | 5 | 18 | 5 | 1 | 23 | 3 | 5 | 5 | 5 | 4.0 | 58 | +18.014 | 5708630 | 43 | 1 | 1:27.418 | 218.385 | 1 | kovalainen | \N | KOV | Heikki | Kovalainen | 1981-10-19 | Finnish | 2008 | 1 | 1 | Australian Grand Prix | 2008-03-16 | \N | mclaren | Heikki Kovalainen |
| 2 | 27 | 19 | 1 | 1 | 22 | 9 | 5 | 5 | 5 | 4.0 | 56 | +46.548 | 5525103 | 53 | 3 | 1:35.462 | 209.033 | 1 | hamilton | 44 | HAM | Lewis | Hamilton | 1985-01-07 | British | 2008 | 2 | 2 | Malaysian Grand Prix | 2008-03-23 | \N | mclaren | Lewis Hamilton |
| 3 | 25 | 19 | 5 | 1 | 23 | 8 | 3 | 3 | 3 | 6.0 | 56 | +38.450 | 5517005 | 19 | 7 | 1:35.922 | 208.031 | 1 | kovalainen | \N | KOV | Heikki | Kovalainen | 1981-10-19 | Finnish | 2008 | 2 | 2 | Malaysian Grand Prix | 2008-03-23 | \N | mclaren | Heikki Kovalainen |
| 4 | 57 | 20 | 1 | 1 | 22 | 3 | 13 | 13 | 13 | 0.0 | 56 | \N | \N | 25 | 19 | 1:35.520 | 203.969 | 11 | hamilton | 44 | HAM | Lewis | Hamilton | 1985-01-07 | British | 2008 | 3 | 3 | Bahrain Grand Prix | 2008-04-06 | \N | mclaren | Lewis Hamilton |
#Circuits
df_circuits = circuits.groupby('country').agg({'name':'count'}).reset_index()
df_circuits.rename({'name':'circuits_count'},axis=1,inplace=True)
#Drivers
df_drivers = drivers.groupby('nationality').agg({'driverRef':'count'}).reset_index()
df_drivers = df_drivers.rename({'driverRef':'driver_count'},axis=1)
#Constructors
df_constructors = constructors.groupby('nationality').agg({'constructorRef':'count'}).reset_index()
df_constructors = df_constructors.rename({'constructorRef':'constructors_count'},axis=1)
df1=df_circuits.sort_values('circuits_count',ascending=True)
df2=df_drivers.sort_values('driver_count',ascending=True)
df3=df_constructors.sort_values('constructors_count',ascending=True)
from plotly.subplots import make_subplots
fig = make_subplots(
rows=1, cols=3,
subplot_titles=('Total circuits per country', 'Total drivers per country','Total constructors per country'),
horizontal_spacing = 0.1,
vertical_spacing = 0.5)
fig.add_trace(go.Bar(
x=df1['circuits_count'],
y=df1["country"],
hovertext='Circuits',
orientation='h'),
row=1, col=1)
fig.add_trace(go.Bar(
x=df2['driver_count'],
y=df2["nationality"],
hovertext='Drivers',
orientation='h'),
row=1, col=2)
fig.add_trace(go.Bar(
x=df3['constructors_count'],
y=df3["nationality"],
hovertext='Constructors',
orientation='h'),
row=1, col=3)
fig.update_layout(title_text='<b> F1 countries information [Circuits,Drivers,Constructors]<b>',
titlefont={'size':25},
title_x=0.33,
showlegend=False,
autosize=True,
height=1000,
template='ggplot2',
paper_bgcolor='orange'
)
fig.show()
from folium import plugins
coord=[]
for lat,lng in zip(circuits['lat'],circuits['lng']):
coord.append([lat,lng])
maps = folium.Map(location=[45.3656,9.1651],zoom_start=5,max_bounds=True,no_wrap=True,tiles='cartodbpositron')
folium.plugins.Fullscreen().add_to(maps)
for i,j in zip(coord,circuits.name):
marker = folium.Marker(
location=i,
icon=folium.Icon(icon="star",color='red'),
popup="<strong>{0}</strong>".format(j))
marker.add_to(maps)
maps
head = 10
#Driver wins
dfDriverWins = dfRaceResults[(dfRaceResults['position']== '1')]
dfDriverWins['position_rank'] = dfDriverWins['position'].astype(int)
dfDriverWins = dfDriverWins.groupby(['full_name','nationality_x'])['position_rank'].sum().reset_index()
dfDriverWins = dfDriverWins.sort_values(by=['position_rank'], ascending=False).head(head)
#Driver poles
dfDriverPoles = dfRaceResults[dfRaceResults['grid']== 1].groupby(by=['full_name','nationality_x'])['grid'].sum().reset_index()
dfDriverPoles = dfDriverPoles.sort_values(by=['grid'], ascending=False).head(head)
#Driver titles
dfDriverSum = dfRaceResults.groupby(['year','full_name'])['points'].sum().reset_index()
dfDriverTiles = dfDriverSum.loc[dfDriverSum.reset_index().groupby(['year'])['points'].idxmax()]
dfDriverTiles = dfDriverTiles['full_name'].value_counts().reset_index()
dfDriverTiles.rename(columns={'index':'driver','full_name':'titles'}, inplace = True)
dfDriverTiles = dfDriverTiles.sort_values(by=['titles'], ascending=False).head(head)
#Driver podiums
dfDriverPodiums = dfRaceResults[((dfRaceResults['positionText'].isin(['1','2','3']) ))]
dfDriverPodiums['position_rank'] = dfDriverPodiums['positionText']
dfDriverPodiums = dfDriverPodiums.groupby(['full_name','nationality_x'])['position_rank'].count().reset_index()
dfDriverPodiums = dfDriverPodiums.sort_values(by=['position_rank'], ascending=False).head(head)
#Driver points (not adjusted to current points system(since 2010))
dfDriverPoints = dfRaceResults.groupby(['full_name','nationality_x'])['points'].sum().reset_index()
dfDriverPoints = dfDriverPoints.sort_values(by=['points'], ascending=False).head(head)
#Drivers fastest laps
dfDriverFastestLap = dfRaceResults[(dfRaceResults['rank']== '1')]
dfDriverFastestLap['lap_rank'] = dfDriverFastestLap['rank'].astype(int)
dfDriverFastestLap = dfDriverFastestLap.groupby(['full_name','nationality_x'])['lap_rank'].sum().reset_index()
dfDriverFastestLap = dfDriverFastestLap.sort_values(by=['lap_rank'], ascending=False).head(head)
fig = make_subplots(
rows=2, cols=3,
subplot_titles=('Drivers with most wins','Drivers with most poles','Drivers with most titles','Drivers with most podiums','Drivers with most points scored in races','Drivers with most fastest laps'),
horizontal_spacing = 0.12,
vertical_spacing = 0.25)
fig.add_trace(go.Bar(
x=dfDriverWins['full_name'],
y=dfDriverWins["position_rank"],
hovertext=dfDriverWins['nationality_x'],
orientation='v'),
row=1, col=1)
fig.add_trace(go.Bar(
x=dfDriverPoles['full_name'],
y=dfDriverPoles['grid'],
hovertext = dfDriverPoles['nationality_x'],
orientation='v'),
row=1, col=2)
fig.add_trace(go.Bar(
x=dfDriverTiles['driver'],
y=dfDriverTiles['titles'],
orientation='v'),
row=1, col=3)
fig.add_trace(go.Bar(
x=dfDriverPodiums['full_name'],
y=dfDriverPodiums["position_rank"],
hovertext=dfDriverPodiums['nationality_x'],
orientation='v'),
row=2, col=1)
fig.add_trace(go.Bar(
x=dfDriverPoints['full_name'],
y=dfDriverPoints["points"],
hovertext=dfDriverPoints['nationality_x'],
orientation='v'),
row=2, col=2)
fig.add_trace(go.Bar(
x=dfDriverFastestLap['full_name'],
y=dfDriverFastestLap['lap_rank'],
hovertext=dfDriverFastestLap['nationality_x'],
orientation='v'),
row=2, col=3)
fig.update_layout(title_text='<b> F1 drivers all time records<b>',
titlefont={'size':25},
title_x=0.5,
showlegend=False,
autosize=True,
height=1000,
template = "plotly_dark"
)
fig.show()
Notes:
head = 10
#Constructor wins
dfConstructorWins = dfRaceResults[(dfRaceResults['position']== '1')]
dfConstructorWins['position_rank'] = dfConstructorWins['position'].astype(int)
dfConstructorWins = dfConstructorWins.groupby(['constructorRef'])['position_rank'].sum().reset_index()
dfConstructorWins = dfConstructorWins.sort_values(by=['position_rank'], ascending=False).head(head)
#Constructor poles
dfConstructorPoles = dfRaceResults[dfRaceResults['grid']== 1].groupby(by=['constructorRef'])['grid'].sum().reset_index()
dfConstructorPoles = dfConstructorPoles.sort_values(by=['grid'], ascending=False).head(head)
#Constructor titles(since 1958)
dfFilteredResults=dfRaceResults[(dfRaceResults['year'] > 1958) & (dfRaceResults['year'] < 2022)]
dfConstructorSum = dfFilteredResults.groupby(['year','constructorRef'])['points'].sum().reset_index()
dfConstructorTiles = dfConstructorSum.loc[dfConstructorSum.reset_index().groupby(['year'])['points'].idxmax()]
dfConstructorTiles = dfConstructorTiles['constructorRef'].value_counts().reset_index()
dfConstructorTiles.rename(columns={'index':'constructor','constructorRef':'titles'}, inplace = True)
dfConstructorTiles = dfConstructorTiles.sort_values(by=['titles'], ascending=False).head(head)
#Constructor podiums finishes
dfConstructorPodiums = dfRaceResults[((dfRaceResults['positionText'].isin(['1','2','3']) ))]
dfConstructorPodiums['position_rank'] = dfConstructorPodiums['positionText']
dfConstructorPodiums = dfConstructorPodiums.groupby(['constructorRef'])['position_rank'].count().reset_index()
dfConstructorPodiums = dfConstructorPodiums.sort_values(by=['position_rank'], ascending=False).head(head)
#Constructor points (not adjusted to current points system(since 2010))
dfConstructorPoints = dfRaceResults.groupby(['constructorRef'])['points'].sum().reset_index()
dfConstructorPoints = dfConstructorPoints.sort_values(by=['points'], ascending=False).head(head)
#Constructor fastest laps
dfConstructorFastestLap = dfRaceResults[(dfRaceResults['rank']== '1')]
dfConstructorFastestLap['lap_rank'] = dfConstructorFastestLap['rank'].astype(int)
dfConstructorFastestLap = dfConstructorFastestLap.groupby(['constructorRef'])['lap_rank'].sum().reset_index()
dfConstructorFastestLap = dfConstructorFastestLap.sort_values(by=['lap_rank'], ascending=False).head(head)
fig = make_subplots(
rows=2, cols=3,
subplot_titles=('Constructors with most wins','Constructors with most poles','Constructor with most constructor titles','Constructors with most podium finishes','Constructors with most points scored in races','Constructors with most fastest laps'),
horizontal_spacing = 0.12,
vertical_spacing = 0.25)
fig.add_trace(go.Bar(
x=dfConstructorWins['constructorRef'],
y=dfConstructorWins["position_rank"],
orientation='v'),
row=1, col=1)
fig.add_trace(go.Bar(
x=dfConstructorPoles['constructorRef'],
y=dfConstructorPoles['grid'],
orientation='v'),
row=1, col=2)
fig.add_trace(go.Bar(
x=dfConstructorTiles['constructor'],
y=dfConstructorTiles['titles'],
orientation='v'),
row=1, col=3)
fig.add_trace(go.Bar(
x=dfConstructorPodiums['constructorRef'],
y=dfConstructorPodiums["position_rank"],
orientation='v'),
row=2, col=1)
fig.add_trace(go.Bar(
x=dfConstructorPoints['constructorRef'],
y=dfConstructorPoints["points"],
orientation='v'),
row=2, col=2)
fig.add_trace(go.Bar(
x=dfConstructorFastestLap['constructorRef'],
y=dfConstructorFastestLap['lap_rank'],
orientation='v'),
row=2, col=3)
fig.update_layout(title_text='<b> F1 constructor all time records<b>',
titlefont={'size':25},
title_x=0.5,
showlegend=False,
autosize=True,
height=1000,
template = "plotly_dark",
)
fig.show()
Notes:
#Driver wins most per season
dfRaceResults[dfRaceResults.position== 1].groupby(['year', 'full_name']).resultId.count().groupby('year')
dfDriverWins = dfRaceResults[(dfRaceResults['position']== '1')]
dfDriverWins['wins_per_season'] = dfDriverWins['position'].astype(int)
dfDriverWins = dfDriverWins.groupby(['full_name','year'])['wins_per_season'].count().reset_index()
dfDriverWins = dfDriverWins.sort_values(['year','wins_per_season'],ascending=[True,False]).drop_duplicates(['year'])
#Driver poles most per season
dfDriverPoles = dfRaceResults[dfRaceResults['grid']== 1].groupby(by=['full_name','year'])['grid'].sum().reset_index()
dfDriverPoles = dfDriverPoles.sort_values(['year','grid'],ascending=[True,False]).drop_duplicates(['year'])
#Driver most podiums per season
dfDriverPodiums = dfRaceResults[((dfRaceResults['positionText'].isin(['1','2','3']) ))]
dfDriverPodiums['podiums_per_season'] = dfDriverPodiums['positionText']
dfDriverPodiums = dfDriverPodiums.groupby(['full_name','year'])['podiums_per_season'].count().reset_index()
dfDriverPodiums = dfDriverPodiums.sort_values(['year','podiums_per_season'],ascending=[True,False]).drop_duplicates(['year'])
fig = make_subplots(
rows=3, cols=1,
subplot_titles=('Most wins per season','Most poles per season','Most podiums per season'),
horizontal_spacing = 0.5,
vertical_spacing = 0.12)
fig.add_trace(go.Bar(
x=dfDriverWins['year'],
y=dfDriverWins["wins_per_season"],
hovertext=dfDriverWins['full_name'],
orientation='v'),
row=1, col=1)
fig.add_trace(go.Bar(
x=dfDriverPoles['year'],
y=dfDriverPoles["grid"],
hovertext=dfDriverPoles['full_name'],
orientation='v'),
row=2, col=1)
fig.add_trace(go.Bar(
x=dfDriverPodiums['year'],
y=dfDriverPodiums["podiums_per_season"],
hovertext=dfDriverPodiums['full_name'],
orientation='v'),
row=3, col=1)
fig.update_layout(title_text='<b> F1 most of the every season record<b>',
titlefont={'size':25},
title_x=0.5,
showlegend=False,
autosize=True,
height=1000,
template = "plotly_white"
)
fig.show()
traces = []
buttons = []
updatemenus = [{'active':0, "buttons":buttons}]
driver_leaderboard = dfRaceResults.groupby(['year','full_name']).agg({'points':'sum'}).reset_index()
driver_leaderboard = driver_leaderboard.sort_values(['year','points'],ascending=[True,False])
years = sorted(driver_leaderboard.year.unique())
for i, year in enumerate(years):
visible = [False] * len(years)
visible[i] = True
df = driver_leaderboard[driver_leaderboard.year == year]
colors = ['red',] * len(df.full_name.unique())
colors[0] = 'gold'
colors[1] = 'silver'
colors[2] = '#cd7f32'
traces.append(
px.bar(data_frame=df,x='full_name', y='points').update_traces(visible=True if i==0 else False,marker_color=colors).data[0]
)
buttons.append(dict(label=str(year),
method="update",
args=[{"visible":visible},
{"title":f"Driver leaderboard season {year}"}]))
fig = go.Figure(data=traces,
layout=dict(updatemenus=updatemenus))
fig.update_layout(title='Driver leaderboard season 1950',title_x=0.5,template='ggplot2')
fig.show()
Notes:
traces = []
buttons = []
updatemenus = [{'active':0, "buttons":buttons}]
dfFilteredResults=dfRaceResults[(dfRaceResults['year'] > 1958)]
constructor_leaderboard = dfFilteredResults.groupby(['year','constructorRef']).agg({'points':'sum'}).reset_index()
constructor_leaderboard = constructor_leaderboard.sort_values(['year','points'],ascending=[True,False])
years = sorted(constructor_leaderboard.year.unique())
for i, year in enumerate(years):
visible = [False] * len(years)
visible[i] = True
df = constructor_leaderboard[constructor_leaderboard.year == year]
colors = ['red'] * len(df.constructorRef.unique())
colors[0] = 'gold'
colors[1] = 'silver'
colors[2] = '#cd7f32'
traces.append(
px.bar(data_frame=df,x='constructorRef', y='points').update_traces(visible=True if i==0 else False,marker_color=colors).data[0]
)
buttons.append(dict(label=str(year),
method="update",
args=[{"visible":visible},
{"title":f"Constructor leaderboard season {year}"}]))
fig = go.Figure(data=traces,
layout=dict(updatemenus=updatemenus))
fig.update_layout(title='Constructor leaderboard season 1958',title_x=0.5,template='ggplot2')
fig.show()
def championship_battle(year):
season = dfRaceResults[dfRaceResults.year==year]
championship_points = pd.DataFrame(season.groupby(['raceId', 'full_name'])['points'].sum().groupby('full_name').cumsum())
championship_points = championship_points.reset_index()
return championship_points.sort_values(['raceId','points'],ascending=[True,True])
dropdown = widgets.Dropdown(options=sorted(dfRaceResults.year.unique()),value=2021,description='Season')
display(dropdown)
Dropdown(description='Season', index=71, options=(1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, …
df = championship_battle(dropdown.value)
fig = px.bar(df, y="full_name", x="points",animation_frame="raceId", range_x=[0,500])
fig.update_layout(title_text = ('<b> F1 driver championship battle of <b>'+ str(dropdown.value)),
titlefont={'size':15},
title_x=0.5,
showlegend=False,
autosize=True,
height=1000,
template='plotly_dark',
)
fig.show()
def con_championship_battle(year):
dfFilteredResults=dfRaceResults[(dfRaceResults['year'] > 1958)]
season = dfFilteredResults[dfFilteredResults.year==year]
championship_points = pd.DataFrame(season.groupby(['raceId', 'constructorRef'])['points'].sum().groupby('constructorRef').cumsum())
championship_points = championship_points.reset_index()
return championship_points.sort_values(['raceId','points'],ascending=[True,True])
dropdown = widgets.Dropdown(options=sorted(dfFilteredResults.year.unique()),value=2021,description='Season')
display(dropdown)
Dropdown(description='Season', index=62, options=(1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, …
df = con_championship_battle(dropdown.value)
fig = px.bar(df, y="constructorRef", x="points",animation_frame="raceId", range_x=[0,800])
fig.update_layout(title_text = ('<b> F1 constructor championship battle of <b>'+ str(dropdown.value)),
titlefont={'size':15},
title_x=0.5,
showlegend=False,
autosize=True,
height=1000,
template='plotly_dark',
)
fig.show()